Skip to content
This repository has been archived by the owner on Feb 25, 2023. It is now read-only.

Commit

Permalink
fix: recovery object from page reload
Browse files Browse the repository at this point in the history
  • Loading branch information
dotennin committed Jul 12, 2020
1 parent 2156c62 commit 92e650c
Show file tree
Hide file tree
Showing 8 changed files with 347 additions and 302 deletions.
378 changes: 191 additions & 187 deletions dist/bundle.user.js

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions src/containers/DownloadList/Operation.tsx
Expand Up @@ -25,7 +25,7 @@ function Operation({ fsId, status }: ReturnType<typeof mapStoreToProps> & IProps
}
targetItem.progress.status = StatusTypes.stopped
targetItem.progress.request?.abort && targetItem.progress.request.abort()
clearInterval(targetItem.progress.intervalId!)
clearInterval(targetItem.progress.intervalId)

dispatch(addNextDownloadRequest())
return false
Expand All @@ -34,7 +34,7 @@ function Operation({ fsId, status }: ReturnType<typeof mapStoreToProps> & IProps
const deleteItem = () => {
if (targetItem) {
targetItem.progress.request?.abort && targetItem.progress.request.abort()
clearInterval(targetItem.progress.intervalId!)
clearInterval(targetItem.progress.intervalId)
delete InstanceForSystem.allDownloads[fsId]
dispatch(downloadModule.actions.removeItem({ fsId }))
}
Expand All @@ -51,6 +51,7 @@ function Operation({ fsId, status }: ReturnType<typeof mapStoreToProps> & IProps
viewBox="0 0 24 24"
width="24"
onClick={() => {
console.log(targetItem)
dispatch(fetchItem(targetItem))
}}
>
Expand Down
3 changes: 1 addition & 2 deletions src/containers/FloatingButtons.tsx
Expand Up @@ -42,10 +42,9 @@ const FloatingButtons: React.FC<ReturnType<typeof mapStoreToProps>> = ({ autoSta

const newItems = { ...downloadItems }
const { allDownloads } = InstanceForSystem
console.log(allDownloads)
selectedList.forEach((item) => {
if (typeof downloadItems[item.fsId] === 'undefined') {
item.progress.status = StatusTypes.inQueued
item.progress.status = StatusTypes.stopped
const { intervalId, percentCount, speedOverlay, status } = item.progress
allDownloads[item.fsId] = item
newItems[item.fsId] = { intervalId, percentCount, speedOverlay, status }
Expand Down
115 changes: 59 additions & 56 deletions src/containers/Preferences.tsx
Expand Up @@ -7,12 +7,13 @@ import { InstanceForSystem } from '../services/InstaceForSystem'
import { IStoreState } from '../store'
import interfaceModule from '../modules/interfaceModule'
import { downloadableSelector } from '../selectors'
import styled from 'styled-components'

// const CustomModal = styled(Modal)`
// .modal-window {
// max-width: 500px;
// }
// `
const Wrapper = styled.div`
.modal-window {
max-width: 500px;
}
`

const mapStoreToProps = (store: IStoreState) => ({
configModalOpen: store.interface.configModalOpen,
Expand Down Expand Up @@ -41,58 +42,60 @@ function Preferences({
setMaxDownloadCount,
}: ReturnType<typeof mapStoreToProps> & ReturnType<typeof mapActionsToProps>) {
return (
<Modal open={configModalOpen} close={closeModal}>
<Form action="#">
<header style={{ margin: '0 0 20px 0' }}>
<h2 style={{ margin: '0 0 5px 0' }}>下载设置</h2>
<div
style={{
fontSize: '90%',
color: '#999',
}}
>
如果下载经常出错,建议将下载数设置为1
</div>
</header>
<FormField>
<label htmlFor={'auto-start'}>自动下载</label>
<div>
<input
type="checkbox"
name="checkbox"
value="true"
checked={autoStart}
id="auto-start"
tabIndex={1}
onChange={setAutoStart}
/>
</div>
</FormField>
<FormField>
<legend>最大同时下载数</legend>
<div>
<select
defaultValue={maxDownloadCount}
id="max-download-count"
className="field select medium"
tabIndex={2}
onChange={setMaxDownloadCount}
<Wrapper>
<Modal open={configModalOpen} close={closeModal}>
<Form action="#">
<header style={{ margin: '0 0 20px 0' }}>
<h2 style={{ margin: '0 0 5px 0' }}>下载设置</h2>
<div
style={{
fontSize: '90%',
color: '#999',
}}
>
{/* Generate numbers with 1-maxDownloadCount */}
{[...Array(InstanceForSystem.maxDownloadCount).keys()]
.map((i) => ++i)
.map((i, key) => {
return (
<option key={key} value={i}>
{i}
</option>
)
})}
</select>
</div>
</FormField>
</Form>
</Modal>
如果下载经常出错,建议将下载数设置为1
</div>
</header>
<FormField>
<label htmlFor={'auto-start'}>自动下载</label>
<div>
<input
type="checkbox"
name="checkbox"
value="true"
checked={autoStart}
id="auto-start"
tabIndex={1}
onChange={setAutoStart}
/>
</div>
</FormField>
<FormField>
<legend>最大同时下载数</legend>
<div>
<select
defaultValue={maxDownloadCount}
id="max-download-count"
className="field select medium"
tabIndex={2}
onChange={setMaxDownloadCount}
>
{/* Generate numbers with 1-maxDownloadCount */}
{[...Array(InstanceForSystem.maxDownloadCount).keys()]
.map((i) => ++i)
.map((i, key) => {
return (
<option key={key} value={i}>
{i}
</option>
)
})}
</select>
</div>
</FormField>
</Form>
</Modal>
</Wrapper>
)
}

Expand Down
4 changes: 3 additions & 1 deletion src/modules/downloadModule.ts
Expand Up @@ -57,7 +57,9 @@ const downloadModule = createSlice({
export const addNextDownloadRequest = (): AppThunk => (dispatch) => {
const { allDownloads } = InstanceForSystem
Object.values(allDownloads)
.filter((item) => item.progress.status === StatusTypes.inQueued)
.filter((item) => {
return item.progress.status === StatusTypes.inQueued
})
.forEach((item) => {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
dispatch(fetchItem(item))
Expand Down
34 changes: 27 additions & 7 deletions src/services/InstaceForSystem.ts
@@ -1,27 +1,43 @@
import { IItem, StatusTypes, ValueTypes } from '../types'
import { IItem, IProgress, StatusTypes, ValueTypes } from '../types'
import { GM } from '../gmInterface/gmInterface'
import { ItemProxy } from './Item'
import { store } from '../store'
import downloadModule from '../modules/downloadModule'

type ItemObject = Record<ItemProxy['fsId'], ItemProxy>
const InstanceForSystem = {
list: eval(`require('system-core:context/context.js')`).instanceForSystem.list,
maxDownloadCount: 2,
autoStart: true,
allDownloads: {} as ItemObject,

initState: function() {
return new Promise((resolve) => {
const objectFromValue: ItemObject = GM.getValue(ValueTypes.items, {})
const objectFromValue = (GM.getValue(ValueTypes.items, {}) as IItem[]).map((arr) => ItemProxy.Create(arr))
GM.deleteValue(ValueTypes.items)

this.allDownloads = objectFromValue
const state = store.getState()
const {
interface: { autoStart },
} = state

Object.values(objectFromValue).forEach((item) => {
if (!this.autoStart && item.progress.status === StatusTypes.downloading) {
const downloadItemsForStore: Record<ItemProxy['fsId'], IProgress> = {}
objectFromValue.forEach((item) => {
if (!autoStart && item.progress.status === StatusTypes.downloading) {
// stop downloading item if user set autoStart as false
item.progress.status = StatusTypes.stopped
}

const { intervalId, percentCount, speedOverlay, status } = item.progress
downloadItemsForStore[item.fsId] = { intervalId, percentCount, speedOverlay, status }
this.allDownloads[item.fsId] = item
})

store.dispatch(downloadModule.actions.change({ downloadItems: downloadItemsForStore }))

// if (autoStart) {
// store.dispatch(fetchItem(item))
// }

resolve(this)
})
},
Expand All @@ -48,6 +64,10 @@ const InstanceForSystem = {
})
},
}
InstanceForSystem.initState()

// Resolve store initiation
setTimeout(() => {
InstanceForSystem.initState()
})

export { InstanceForSystem }
108 changes: 62 additions & 46 deletions src/services/Item.ts
@@ -1,8 +1,16 @@
import { IItem, StatusTypes } from '../types'
import { IItem, IProgress, StatusTypes } from '../types'
import { GM } from '../gmInterface/gmInterface'
import { store } from '../store'
import downloadModule from '../modules/downloadModule'

/**
* Check the arg whether IItem interface or not
* @param arg
*/
function implementsItem(arg: any): arg is IItem {
return arg !== null && typeof arg === 'object' && typeof arg.fs_id !== 'undefined'
}

export class ProgressProxy {
public intervalId: number | undefined
public request: ReturnType<typeof GM.download> | undefined
Expand All @@ -14,19 +22,22 @@ export class ProgressProxy {
public static Parse(d: any): ProgressProxy {
return ProgressProxy.Create(d)
}
public static Create(fsId: string | number): ProgressProxy {
return new ProgressProxy(fsId)
public static Create(fsId: string | number, defaultState?: IProgress): ProgressProxy {
return new ProgressProxy(fsId, defaultState)
}
private constructor(fsId: string | number) {
private constructor(fsId: string | number, defaultState?: IProgress) {
this.fsId = fsId
this.percentCount = 0
this.speedOverlay = 0
this.status = StatusTypes.unknow
if (defaultState) {
Object.assign(this, defaultState)
} else {
this.percentCount = 0
this.speedOverlay = 0
this.status = StatusTypes.unknow
}
}
set speedOverlay(v: number) {
if (this._speedOverlay === v) return
this._speedOverlay = v
this._percentCount = v
store.dispatch(
downloadModule.actions.updateProgress({
fsId: this.fsId,
Expand Down Expand Up @@ -75,48 +86,53 @@ export class ProgressProxy {
}

export class ItemProxy {
public category: number
public fsId: string | number
public isDir: number
public localCtime: number
public localMtime: number
public md5: string
public operId: number
public path: string
public privacy: number
public serverAtime: number
public serverCtime: number
public serverFilename: string
public serverMtime: number
public share: number
public size: number
public unList: number
public url: string
public progress: ProgressProxy
public category!: number
public fsId!: string | number
public isDir!: number
public localCtime!: number
public localMtime!: number
public md5!: string
public operId!: number
public path!: string
public privacy!: number
public serverAtime!: number
public serverCtime!: number
public serverFilename!: string
public serverMtime!: number
public share!: number
public size!: number
public unList!: number
public url!: string
public progress!: ProgressProxy
public static Parse(d: string): ItemProxy {
return ItemProxy.Create(JSON.parse(d))
}
public static Create(d: IItem): ItemProxy {
public static Create(d: IItem | ItemProxy): ItemProxy {
return new ItemProxy(d)
}
private constructor(d: IItem) {
this.category = d.category
this.fsId = d.fs_id
this.isDir = d.isdir
this.localCtime = d.local_ctime
this.localMtime = d.local_mtime
this.md5 = d.md5
this.operId = d.oper_id
this.path = d.path
this.privacy = d.privacy
this.serverAtime = d.server_atime
this.serverCtime = d.server_ctime
this.serverFilename = d.server_filename
this.serverMtime = d.server_mtime
this.share = d.share
this.size = d.size
this.unList = d.unlist
this.url = d.url
this.progress = ProgressProxy.Create(this.fsId)
private constructor(d: IItem | ItemProxy) {
if (implementsItem(d)) {
this.category = d.category
this.fsId = d.fs_id
this.isDir = d.isdir
this.localCtime = d.local_ctime
this.localMtime = d.local_mtime
this.md5 = d.md5
this.operId = d.oper_id
this.path = d.path
this.privacy = d.privacy
this.serverAtime = d.server_atime
this.serverCtime = d.server_ctime
this.serverFilename = d.server_filename
this.serverMtime = d.server_mtime
this.share = d.share
this.size = d.size
this.unList = d.unlist
this.url = d.url
this.progress = ProgressProxy.Create(this.fsId)
} else {
Object.assign(this, d)
this.progress = ProgressProxy.Create(this.fsId, this.progress)
}
}
}
2 changes: 1 addition & 1 deletion src/services/windowInstance.ts
Expand Up @@ -4,7 +4,7 @@ import { store } from '../store'
import { InstanceForSystem } from './InstaceForSystem'

window.onunload = () => {
GM.setValue(ValueTypes.items, store.getState().download.downloadItems)
GM.setValue(ValueTypes.items, Object.values(InstanceForSystem.allDownloads))

InstanceForSystem.stopAll()
}
Expand Down

0 comments on commit 92e650c

Please sign in to comment.