mirror of
https://github.com/zoriya/react-native-background-downloader.git
synced 2025-12-06 06:56:10 +00:00
fixed error with progressInterval. corrected types & ts config. removed percent from progress event. changed params to object in all events. updated readme. made onProgress starting on app start
This commit is contained in:
495
.eslintrc
495
.eslintrc
@@ -1,495 +0,0 @@
|
|||||||
/*
|
|
||||||
* Eko's ESLint JSON Config file (eslint allows JavaScript-style comments in JSON config files).
|
|
||||||
*/
|
|
||||||
|
|
||||||
{
|
|
||||||
// Enable the ESLint recommended rules as a starting point.
|
|
||||||
// These are rules that report common problems, see https://eslint.org/docs/rules/
|
|
||||||
"extends": "eslint:recommended",
|
|
||||||
|
|
||||||
"parser": "babel-eslint",
|
|
||||||
// Specify the envs (an environment defines global variables that are predefined).
|
|
||||||
// See https://eslint.org/docs/user-guide/configuring#specifying-environments
|
|
||||||
"env": {
|
|
||||||
// Browser global variables.
|
|
||||||
"browser": false,
|
|
||||||
|
|
||||||
// Node.js global variables and Node.js scoping.
|
|
||||||
"node": true,
|
|
||||||
|
|
||||||
// CommonJS global variables and CommonJS scoping (use this for browser-only code that uses Browserify/WebPack).
|
|
||||||
"commonjs": true,
|
|
||||||
|
|
||||||
// Globals common to both Node.js and Browser.
|
|
||||||
"shared-node-browser": true,
|
|
||||||
|
|
||||||
// enable all ECMAScript 6 features except for modules (this automatically sets the ecmaVersion parser option to 6).
|
|
||||||
"es6": true,
|
|
||||||
|
|
||||||
// web workers global variables.
|
|
||||||
"worker": true
|
|
||||||
},
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules
|
|
||||||
"rules": {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Possible Errors https://eslint.org/docs/rules/#possible-errors
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-console
|
|
||||||
"no-console": ["error", { "allow": ["error"] }],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/valid-jsdoc
|
|
||||||
// TODO - valid-jsdoc
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Best Practices https://eslint.org/docs/rules/#best-practices
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/accessor-pairs
|
|
||||||
"accessor-pairs": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/array-callback-return
|
|
||||||
"array-callback-return": ["error", { "allowImplicit": true }],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/block-scoped-var
|
|
||||||
"block-scoped-var": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/curly
|
|
||||||
"curly": ["error", "all"],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/default-case
|
|
||||||
"default-case": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/dot-location
|
|
||||||
"dot-location": ["error", "property"],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/dot-notation
|
|
||||||
"dot-notation": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/eqeqeq
|
|
||||||
"eqeqeq": ["error", "always"],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-alert
|
|
||||||
"no-alert": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-caller
|
|
||||||
"no-caller": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-else-return
|
|
||||||
"no-else-return": ["error", { "allowElseIf": false }],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-eq-null
|
|
||||||
"no-eq-null": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-eval
|
|
||||||
"no-eval": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-extra-bind
|
|
||||||
"no-extra-bind": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-fallthrough
|
|
||||||
"no-fallthrough": ["error", { "commentPattern": "fall-?thr(ough|u)" }],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-floating-decimal
|
|
||||||
"no-floating-decimal": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-implicit-coercion
|
|
||||||
"no-implicit-coercion": ["error", { "allow": ["!!"] }],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-implicit-globals
|
|
||||||
"no-implicit-globals": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-implied-eval
|
|
||||||
"no-implied-eval": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-invalid-this
|
|
||||||
"no-invalid-this": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-iterator
|
|
||||||
"no-iterator": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-labels
|
|
||||||
"no-labels": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-lone-blocks
|
|
||||||
"no-lone-blocks": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-loop-func
|
|
||||||
"no-loop-func": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-magic-numbers
|
|
||||||
"no-magic-numbers": ["error", {
|
|
||||||
"ignore": [
|
|
||||||
0, 1, -1,
|
|
||||||
10, 100, 1000, 10000, 100000, 1000000,
|
|
||||||
1024, 8, 2,
|
|
||||||
24, 60
|
|
||||||
]
|
|
||||||
}],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-multi-spaces
|
|
||||||
"no-multi-spaces": ["error", { "ignoreEOLComments": true, "exceptions": {
|
|
||||||
"Property": true,
|
|
||||||
"VariableDeclarator": true,
|
|
||||||
"ImportDeclaration": true
|
|
||||||
}}],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-multi-str
|
|
||||||
"no-multi-str": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-new
|
|
||||||
"no-new": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-new-wrappers
|
|
||||||
"no-new-wrappers": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-octal-escape
|
|
||||||
"no-octal-escape": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-proto
|
|
||||||
"no-proto": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-return-assign
|
|
||||||
"no-return-assign": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-return-await
|
|
||||||
"no-return-await": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-script-url
|
|
||||||
"no-script-url": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-self-compare
|
|
||||||
"no-self-compare": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-sequences
|
|
||||||
"no-sequences": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-throw-literal
|
|
||||||
"no-throw-literal": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-unmodified-loop-condition
|
|
||||||
"no-unmodified-loop-condition": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-unused-expressions
|
|
||||||
"no-unused-expressions": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-useless-call
|
|
||||||
"no-useless-call": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-useless-concat
|
|
||||||
"no-useless-concat": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-useless-return
|
|
||||||
"no-useless-return": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-void
|
|
||||||
"no-void": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-with
|
|
||||||
"no-with": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/prefer-promise-reject-errors
|
|
||||||
"prefer-promise-reject-errors": ["error", { "allowEmptyReject": true }],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/radix
|
|
||||||
"radix": ["error", "always"],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/require-await
|
|
||||||
"require-await": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/wrap-iife
|
|
||||||
"wrap-iife": ["error", "any"],
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Strict Mode https://eslint.org/docs/rules/#strict-mode
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/strict
|
|
||||||
"strict": ["error", "safe"],
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Variables https://eslint.org/docs/rules/#variables
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-shadow
|
|
||||||
"no-shadow": ["error", { "builtinGlobals": true, "hoist": "all", "allow": [] }],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-shadow-restricted-names
|
|
||||||
"no-shadow-restricted-names": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-undef-init
|
|
||||||
"no-undef-init": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-use-before-define
|
|
||||||
"no-use-before-define": ["error", { "functions": true, "classes": true, "variables": true }],
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Node.js and CommonJS https://eslint.org/docs/rules/#nodejs-and-commonjs
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/global-require
|
|
||||||
"global-require": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-buffer-constructor
|
|
||||||
"no-buffer-constructor": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-new-require
|
|
||||||
"no-new-require": "error",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-path-concat
|
|
||||||
"no-path-concat": "error",
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Stylistic Issues https://eslint.org/docs/rules/#stylistic-issues
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/array-bracket-newline
|
|
||||||
"array-bracket-newline": ["warn", { "multiline": true }],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/array-bracket-spacing
|
|
||||||
"array-bracket-spacing": ["warn", "never"],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/block-spacing
|
|
||||||
"block-spacing": ["warn", "always"],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/brace-style
|
|
||||||
"brace-style": ["warn", "1tbs", { "allowSingleLine": true }],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/camelcase
|
|
||||||
"camelcase": ["warn", { "properties": "always" }],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/capitalized-comments
|
|
||||||
"capitalized-comments": ["warn", "always", { "ignoreInlineComments": true, "ignoreConsecutiveComments": true }],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/comma-dangle
|
|
||||||
"comma-dangle": ["warn", "only-multiline"],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/comma-spacing
|
|
||||||
"comma-spacing": ["warn", { "before": false, "after": true }],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/comma-style
|
|
||||||
"comma-style": ["warn", "last"],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/computed-property-spacing
|
|
||||||
"computed-property-spacing": ["warn", "never"],
|
|
||||||
|
|
||||||
// TODO - discuss with TEAM!
|
|
||||||
// https://eslint.org/docs/rules/consistent-this
|
|
||||||
"consistent-this": ["warn", "that", "_this", "self"],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/eol-last
|
|
||||||
"eol-last": ["warn", "always"],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/func-call-spacing
|
|
||||||
"func-call-spacing": ["warn", "never"],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/func-name-matching
|
|
||||||
"func-name-matching": ["warn", "always"],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/implicit-arrow-linebreak
|
|
||||||
"implicit-arrow-linebreak": ["warn", "beside"],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/indent
|
|
||||||
"indent": ["warn", 4, {
|
|
||||||
"SwitchCase": 1,
|
|
||||||
"FunctionDeclaration": {
|
|
||||||
"parameters": 2,
|
|
||||||
"body": 1
|
|
||||||
},
|
|
||||||
"FunctionExpression": {
|
|
||||||
"parameters": 2,
|
|
||||||
"body": 1
|
|
||||||
},
|
|
||||||
"CallExpression": {
|
|
||||||
"arguments": 1
|
|
||||||
},
|
|
||||||
"ArrayExpression": 1,
|
|
||||||
"ObjectExpression": 1,
|
|
||||||
"ImportDeclaration": 1,
|
|
||||||
"ignoredNodes": [
|
|
||||||
"ConditionalExpression"
|
|
||||||
]
|
|
||||||
}],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/jsx-quotes
|
|
||||||
"jsx-quotes": ["warn", "prefer-double"],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/key-spacing
|
|
||||||
"key-spacing": [
|
|
||||||
"warn",
|
|
||||||
{
|
|
||||||
"singleLine": {
|
|
||||||
"beforeColon": false,
|
|
||||||
"afterColon": true,
|
|
||||||
"mode": "strict"
|
|
||||||
},
|
|
||||||
"multiLine": {
|
|
||||||
"beforeColon": false,
|
|
||||||
"afterColon": true,
|
|
||||||
"mode": "minimum"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/keyword-spacing
|
|
||||||
"keyword-spacing": ["warn", { "before": true, "after": true }],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/linebreak-style
|
|
||||||
"linebreak-style": ["warn", "unix"],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/lines-around-comment
|
|
||||||
"lines-around-comment": ["warn", {
|
|
||||||
"beforeBlockComment": true,
|
|
||||||
"afterBlockComment": false,
|
|
||||||
"beforeLineComment": true,
|
|
||||||
"afterLineComment": false,
|
|
||||||
"allowBlockStart": true,
|
|
||||||
"allowBlockEnd": false,
|
|
||||||
"allowClassStart": true,
|
|
||||||
"allowClassEnd": false,
|
|
||||||
"allowObjectStart": true,
|
|
||||||
"allowObjectEnd": false,
|
|
||||||
"allowArrayStart": true,
|
|
||||||
"allowArrayEnd": false
|
|
||||||
}],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/max-len
|
|
||||||
"max-len": ["warn", {
|
|
||||||
"code": 120,
|
|
||||||
"tabWidth": 4,
|
|
||||||
"ignoreUrls": true,
|
|
||||||
"ignoreComments": true
|
|
||||||
}],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/max-lines
|
|
||||||
"max-lines": ["warn", {
|
|
||||||
"max": 500,
|
|
||||||
"skipBlankLines": true,
|
|
||||||
"skipComments": true
|
|
||||||
}],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/max-statements
|
|
||||||
"max-statements": ["warn", 30],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/max-statements-per-line
|
|
||||||
"max-statements-per-line": ["warn", {
|
|
||||||
"max": 1
|
|
||||||
}],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/multiline-ternary
|
|
||||||
"multiline-ternary": ["warn", "always-multiline"],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/new-cap
|
|
||||||
"new-cap": ["warn", { "newIsCap": true, "capIsNew": true, "properties": true }],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/new-parens
|
|
||||||
"new-parens": "warn",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/newline-per-chained-call
|
|
||||||
"newline-per-chained-call": ["warn", { "ignoreChainWithDepth": 2 }],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-array-constructor
|
|
||||||
"no-array-constructor": "warn",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-bitwise
|
|
||||||
"no-bitwise": "warn",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-lonely-if
|
|
||||||
"no-lonely-if": "warn",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-mixed-operators
|
|
||||||
"no-mixed-operators": "warn",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-multi-assign
|
|
||||||
"no-multi-assign": "warn",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-multiple-empty-lines
|
|
||||||
"no-multiple-empty-lines": ["warn", { "max": 2, "maxEOF": 1, "maxBOF": 0 }],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-negated-condition
|
|
||||||
"no-negated-condition": "warn",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-new-object
|
|
||||||
"no-new-object": "warn",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-tabs
|
|
||||||
"no-tabs": "warn",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-trailing-spaces
|
|
||||||
"no-trailing-spaces": ["warn", { "skipBlankLines": false, "ignoreComments": false }],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-unneeded-ternary
|
|
||||||
"no-unneeded-ternary": ["warn", { "defaultAssignment": false }],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-whitespace-before-property
|
|
||||||
"no-whitespace-before-property": "warn",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/object-curly-newline
|
|
||||||
"object-curly-newline": ["warn", { "consistent": true }],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/object-curly-spacing
|
|
||||||
"object-curly-spacing": ["warn", "always"],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/one-var
|
|
||||||
"one-var": ["error", "never"],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/operator-linebreak
|
|
||||||
"operator-linebreak": ["warn", "after"],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/padded-blocks
|
|
||||||
"padded-blocks": ["warn", "never"],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/quote-props
|
|
||||||
"quote-props": ["warn", "as-needed"],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/quotes
|
|
||||||
"quotes": ["warn", "single", { "avoidEscape": true, "allowTemplateLiterals": true }],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/semi
|
|
||||||
"semi": ["warn", "always"],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/semi-spacing
|
|
||||||
"semi-spacing": ["warn", { "before": false, "after": true }],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/semi-style
|
|
||||||
"semi-style": ["warn", "last"],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/space-before-blocks
|
|
||||||
"space-before-blocks": ["warn", "always"],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/space-before-function-paren
|
|
||||||
"space-before-function-paren": ["warn", "never"],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/space-in-parens
|
|
||||||
"space-in-parens": ["warn", "never"],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/space-infix-ops
|
|
||||||
"space-infix-ops": "warn",
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/space-unary-ops
|
|
||||||
"space-unary-ops": ["warn", { "words": true, "nonwords": false }],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/spaced-comment
|
|
||||||
"spaced-comment": ["warn", "always", { "exceptions": ["-", "/", "=", "*"] }],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/switch-colon-spacing
|
|
||||||
"switch-colon-spacing": ["warn", { "after": true, "before": false }],
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/unicode-bom
|
|
||||||
"unicode-bom": ["error", "never"],
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// ECMAScript 6 https://eslint.org/docs/rules/#ecmascript-6
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/arrow-spacing
|
|
||||||
"arrow-spacing": ["warn", { "before": true, "after": true }]
|
|
||||||
|
|
||||||
// TODO - more ES6 rules
|
|
||||||
},
|
|
||||||
"parserOptions": {
|
|
||||||
"sourceType": "module"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
10
.eslintrc.js
10
.eslintrc.js
@@ -20,6 +20,8 @@ module.exports = {
|
|||||||
plugins: [
|
plugins: [
|
||||||
'react',
|
'react',
|
||||||
'react-hooks',
|
'react-hooks',
|
||||||
|
'jest',
|
||||||
|
'@typescript-eslint',
|
||||||
],
|
],
|
||||||
settings: {
|
settings: {
|
||||||
react: {
|
react: {
|
||||||
@@ -63,9 +65,15 @@ module.exports = {
|
|||||||
'no-class-assign': 'off',
|
'no-class-assign': 'off',
|
||||||
'no-useless-escape': 'off',
|
'no-useless-escape': 'off',
|
||||||
curly: [2, 'multi', 'consistent'],
|
curly: [2, 'multi', 'consistent'],
|
||||||
'react/prop-types': 'off', // TODO: TURN ON AND FIX ALL WARNINGS
|
|
||||||
'react/display-name': 'off',
|
'react/display-name': 'off',
|
||||||
|
'react-hooks/exhaustive-deps': ['warn', {
|
||||||
|
}],
|
||||||
},
|
},
|
||||||
|
overrides: [{
|
||||||
|
files: ['**/*.ts', '**/*.tsx'],
|
||||||
|
parser: '@typescript-eslint/parser',
|
||||||
|
extends: ['plugin:@typescript-eslint/recommended'],
|
||||||
|
}],
|
||||||
globals: {
|
globals: {
|
||||||
describe: 'readonly',
|
describe: 'readonly',
|
||||||
test: 'readonly',
|
test: 'readonly',
|
||||||
|
|||||||
37
README.md
37
README.md
@@ -111,10 +111,10 @@ let task = download({
|
|||||||
metadata: {}
|
metadata: {}
|
||||||
}).begin(({ expectedBytes, headers }) => {
|
}).begin(({ expectedBytes, headers }) => {
|
||||||
console.log(`Going to download ${expectedBytes} bytes!`)
|
console.log(`Going to download ${expectedBytes} bytes!`)
|
||||||
}).progress(percent => {
|
}).progress(({ bytesDownloaded, bytesTotal }) => {
|
||||||
console.log(`Downloaded: ${percent * 100}%`)
|
console.log(`Downloaded: ${bytesDownloaded / bytesTotal * 100}%`)
|
||||||
}).done(() => {
|
}).done(({ bytesDownloaded, bytesTotal }) => {
|
||||||
console.log('Download is done!')
|
console.log('Download is done!', { bytesDownloaded, bytesTotal })
|
||||||
|
|
||||||
// PROCESS YOUR STUFF
|
// PROCESS YOUR STUFF
|
||||||
|
|
||||||
@@ -148,10 +148,10 @@ import RNBackgroundDownloader from '@kesha-antonov/react-native-background-downl
|
|||||||
let lostTasks = await RNBackgroundDownloader.checkForExistingDownloads()
|
let lostTasks = await RNBackgroundDownloader.checkForExistingDownloads()
|
||||||
for (let task of lostTasks) {
|
for (let task of lostTasks) {
|
||||||
console.log(`Task ${task.id} was found!`)
|
console.log(`Task ${task.id} was found!`)
|
||||||
task.progress(percent => {
|
task.progress(({ bytesDownloaded, bytesTotal }) => {
|
||||||
console.log(`Downloaded: ${percent * 100}%`)
|
console.log(`Downloaded: ${bytesDownloaded / bytesTotal * 100}%`)
|
||||||
}).done(() => {
|
}).done(({ bytesDownloaded, bytesTotal }) => {
|
||||||
console.log('Download is done!')
|
console.log('Download is done!', { bytesDownloaded, bytesTotal })
|
||||||
}).error(error => {
|
}).error(error => {
|
||||||
console.log('Download canceled due to error: ', error)
|
console.log('Download canceled due to error: ', error)
|
||||||
})
|
})
|
||||||
@@ -182,10 +182,10 @@ let task = RNBackgroundDownloader.download({
|
|||||||
}
|
}
|
||||||
}).begin(({ expectedBytes, headers }) => {
|
}).begin(({ expectedBytes, headers }) => {
|
||||||
console.log(`Going to download ${expectedBytes} bytes!`)
|
console.log(`Going to download ${expectedBytes} bytes!`)
|
||||||
}).progress(percent => {
|
}).progress(({ bytesDownloaded, bytesTotal }) => {
|
||||||
console.log(`Downloaded: ${percent * 100}%`)
|
console.log(`Downloaded: ${bytesDownloaded / bytesTotal * 100}%`)
|
||||||
}).done(() => {
|
}).done(({ bytesDownloaded, bytesTotal }) => {
|
||||||
console.log('Download is done!')
|
console.log('Download is done!', { bytesDownloaded, bytesTotal })
|
||||||
}).error(error => {
|
}).error(error => {
|
||||||
console.log('Download canceled due to error: ', error)
|
console.log('Download canceled due to error: ', error)
|
||||||
})
|
})
|
||||||
@@ -243,7 +243,6 @@ A class representing a download task created by `RNBackgroundDownloader.download
|
|||||||
| -------------- | ------ | ---------------------------------------------------------------------------------------------------- |
|
| -------------- | ------ | ---------------------------------------------------------------------------------------------------- |
|
||||||
| `id` | String | The id you gave the task when calling `RNBackgroundDownloader.download` |
|
| `id` | String | The id you gave the task when calling `RNBackgroundDownloader.download` |
|
||||||
| `metadata` | Object | The metadata you gave the task when calling `RNBackgroundDownloader.download` |
|
| `metadata` | Object | The metadata you gave the task when calling `RNBackgroundDownloader.download` |
|
||||||
| `percent` | Number | The current percent of completion of the task between 0 and 1 |
|
|
||||||
| `bytesDownloaded` | Number | The number of bytes currently written by the task |
|
| `bytesDownloaded` | Number | The number of bytes currently written by the task |
|
||||||
| `bytesTotal` | Number | The number bytes expected to be written by this task or more plainly, the file size being downloaded |
|
| `bytesTotal` | Number | The number bytes expected to be written by this task or more plainly, the file size being downloaded |
|
||||||
|
|
||||||
@@ -304,12 +303,12 @@ Use these methods to stay updated on what's happening with the task.
|
|||||||
|
|
||||||
All callback methods return the current instance of the `DownloadTask` for chaining.
|
All callback methods return the current instance of the `DownloadTask` for chaining.
|
||||||
|
|
||||||
| Function | Callback Arguments | Info |
|
| Function | Callback Arguments | Info|
|
||||||
| ---------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
| ---------- | --------------------------------- | ---- |
|
||||||
| `begin` | { expectedBytes, headers } | Called when the first byte is received. 💡: this is good place to check if the device has enough storage space for this download |
|
| `begin` | { expectedBytes, headers } | Called when the first byte is received. 💡: this is good place to check if the device has enough storage space for this download |
|
||||||
| `progress` | percent, bytesDownloaded, bytesTotal | Called at max every 1.5s so you can update your progress bar accordingly |
|
| `progress` | { bytesDownloaded, bytesTotal } | Called at max every 1.5s so you can update your progress bar accordingly |
|
||||||
| `done` | | Called when the download is done, the file is at the destination you've set |
|
| `done` | { bytesDownloaded, bytesTotal } | Called when the download is done, the file is at the destination you've set |
|
||||||
| `error` | error | Called when the download stops due to an error |
|
| `error` | { error, errorCode } | Called when the download stops due to an error |
|
||||||
|
|
||||||
### `pause()`
|
### `pause()`
|
||||||
Pauses the download
|
Pauses the download
|
||||||
|
|||||||
@@ -19,13 +19,12 @@ public class OnProgress extends Thread {
|
|||||||
private Cursor cursor;
|
private Cursor cursor;
|
||||||
private int lastBytesDownloaded;
|
private int lastBytesDownloaded;
|
||||||
private int bytesTotal;
|
private int bytesTotal;
|
||||||
private int progressInterval = 300;
|
|
||||||
|
|
||||||
private RNBGDTaskConfig config;
|
private RNBGDTaskConfig config;
|
||||||
private DeviceEventManagerModule.RCTDeviceEventEmitter ee;
|
private DeviceEventManagerModule.RCTDeviceEventEmitter ee;
|
||||||
|
|
||||||
public OnProgress(RNBGDTaskConfig config, long downloadId,
|
public OnProgress(RNBGDTaskConfig config, long downloadId,
|
||||||
DeviceEventManagerModule.RCTDeviceEventEmitter ee, Downloader downloader, int progressInterval) {
|
DeviceEventManagerModule.RCTDeviceEventEmitter ee, Downloader downloader) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
|
||||||
this.downloadId = downloadId;
|
this.downloadId = downloadId;
|
||||||
@@ -34,9 +33,6 @@ public class OnProgress extends Thread {
|
|||||||
|
|
||||||
this.ee = ee;
|
this.ee = ee;
|
||||||
this.downloader = downloader;
|
this.downloader = downloader;
|
||||||
if (progressInterval > 0) {
|
|
||||||
this.progressInterval = progressInterval;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleInterrupt() {
|
private void handleInterrupt() {
|
||||||
@@ -56,7 +52,7 @@ public class OnProgress extends Thread {
|
|||||||
Log.d("RNBackgroundDownloader", "RNBD: OnProgress-1. downloadId " + downloadId);
|
Log.d("RNBackgroundDownloader", "RNBD: OnProgress-1. downloadId " + downloadId);
|
||||||
while (downloadId > 0) {
|
while (downloadId > 0) {
|
||||||
try {
|
try {
|
||||||
Log.d("RNBackgroundDownloader", "RNBD: OnProgress-2. downloadId " + downloadId);
|
Log.d("RNBackgroundDownloader", "RNBD: OnProgress-2. downloadId " + downloadId + " destination " + config.destination);
|
||||||
|
|
||||||
cursor = downloader.downloadManager.query(query);
|
cursor = downloader.downloadManager.query(query);
|
||||||
|
|
||||||
@@ -77,7 +73,7 @@ public class OnProgress extends Thread {
|
|||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
} else {
|
} else {
|
||||||
Log.d("RNBackgroundDownloader", "RNBD: OnProgress-2.3. downloadId " + downloadId);
|
Log.d("RNBackgroundDownloader", "RNBD: OnProgress-2.3. downloadId " + downloadId);
|
||||||
Thread.sleep(progressInterval);
|
Thread.sleep(config.progressInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
// get total bytes of the file
|
// get total bytes of the file
|
||||||
@@ -101,7 +97,6 @@ public class OnProgress extends Thread {
|
|||||||
params.putString("id", config.id);
|
params.putString("id", config.id);
|
||||||
params.putInt("bytesDownloaded", (int) lastBytesDownloaded);
|
params.putInt("bytesDownloaded", (int) lastBytesDownloaded);
|
||||||
params.putInt("bytesTotal", (int) bytesTotal);
|
params.putInt("bytesTotal", (int) bytesTotal);
|
||||||
params.putDouble("percent", ((double) lastBytesDownloaded / bytesTotal));
|
|
||||||
|
|
||||||
HashMap<String, WritableMap> progressReports = new HashMap<>();
|
HashMap<String, WritableMap> progressReports = new HashMap<>();
|
||||||
progressReports.put(config.id, params);
|
progressReports.put(config.id, params);
|
||||||
|
|||||||
@@ -8,12 +8,14 @@ public class RNBGDTaskConfig implements Serializable {
|
|||||||
public String destination;
|
public String destination;
|
||||||
public String metadata = "{}";
|
public String metadata = "{}";
|
||||||
public boolean reportedBegin;
|
public boolean reportedBegin;
|
||||||
|
public int progressInterval;
|
||||||
|
|
||||||
public RNBGDTaskConfig(String id, String url, String destination, String metadata) {
|
public RNBGDTaskConfig(String id, String url, String destination, String metadata, int progressInterval) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.destination = destination;
|
this.destination = destination;
|
||||||
this.metadata = metadata;
|
this.metadata = metadata;
|
||||||
this.reportedBegin = false;
|
this.reportedBegin = false;
|
||||||
|
this.progressInterval = progressInterval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,6 +121,8 @@ public class RNBackgroundDownloaderModule extends ReactContextBaseJavaModule {
|
|||||||
WritableMap params = Arguments.createMap();
|
WritableMap params = Arguments.createMap();
|
||||||
params.putString("id", config.id);
|
params.putString("id", config.id);
|
||||||
params.putString("location", config.destination);
|
params.putString("location", config.destination);
|
||||||
|
params.putInt("bytesDownloaded", downloadStatus.getInt("bytesDownloaded"));
|
||||||
|
params.putInt("bytesTotal", downloadStatus.getInt("bytesTotal"));
|
||||||
|
|
||||||
ee.emit("downloadComplete", params);
|
ee.emit("downloadComplete", params);
|
||||||
break;
|
break;
|
||||||
@@ -148,13 +150,20 @@ public class RNBackgroundDownloaderModule extends ReactContextBaseJavaModule {
|
|||||||
public RNBackgroundDownloaderModule(ReactApplicationContext reactContext) {
|
public RNBackgroundDownloaderModule(ReactApplicationContext reactContext) {
|
||||||
super(reactContext);
|
super(reactContext);
|
||||||
|
|
||||||
ReadableMap emptyMap = Arguments.createMap();
|
loadConfigMap();
|
||||||
this.initDownloader(emptyMap);
|
|
||||||
|
|
||||||
downloader = new Downloader(reactContext);
|
downloader = new Downloader(reactContext);
|
||||||
|
|
||||||
IntentFilter filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
|
IntentFilter filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
|
||||||
compatRegisterReceiver(reactContext, downloadReceiver, filter, true);
|
compatRegisterReceiver(reactContext, downloadReceiver, filter, true);
|
||||||
|
|
||||||
|
// iterate over downloadIdToConfig
|
||||||
|
for(Map.Entry<Long, RNBGDTaskConfig> entry : downloadIdToConfig.entrySet()) {
|
||||||
|
Long downloadId = entry.getKey();
|
||||||
|
RNBGDTaskConfig config = entry.getValue();
|
||||||
|
|
||||||
|
startReportingTasks(downloadId, config);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TAKEN FROM
|
// TAKEN FROM
|
||||||
@@ -220,15 +229,6 @@ public class RNBackgroundDownloaderModule extends ReactContextBaseJavaModule {
|
|||||||
return constants;
|
return constants;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ReactMethod
|
|
||||||
public void initDownloader(ReadableMap options) {
|
|
||||||
Log.d(getName(), "RNBD: initDownloader");
|
|
||||||
|
|
||||||
loadConfigMap();
|
|
||||||
|
|
||||||
// TODO. MAYBE REINIT DOWNLOADER
|
|
||||||
}
|
|
||||||
|
|
||||||
private void removeFromMaps(long downloadId) {
|
private void removeFromMaps(long downloadId) {
|
||||||
Log.d(getName(), "RNBD: removeFromMaps");
|
Log.d(getName(), "RNBD: removeFromMaps");
|
||||||
|
|
||||||
@@ -291,7 +291,7 @@ public class RNBackgroundDownloaderModule extends ReactContextBaseJavaModule {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RNBGDTaskConfig config = new RNBGDTaskConfig(id, url, destination, metadata);
|
RNBGDTaskConfig config = new RNBGDTaskConfig(id, url, destination, metadata, progressInterval);
|
||||||
final Request request = new Request(Uri.parse(url));
|
final Request request = new Request(Uri.parse(url));
|
||||||
request.setAllowedOverRoaming(isAllowedOverRoaming);
|
request.setAllowedOverRoaming(isAllowedOverRoaming);
|
||||||
request.setAllowedOverMetered(isAllowedOverMetered);
|
request.setAllowedOverMetered(isAllowedOverMetered);
|
||||||
@@ -333,52 +333,59 @@ public class RNBackgroundDownloaderModule extends ReactContextBaseJavaModule {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
config.reportedBegin = true;
|
startReportingTasks(downloadId, config);
|
||||||
saveConfigMap();
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Log.d(getName(), "RNBD: download-2 downloadId: " + downloadId);
|
private void startReportingTasks(Long downloadId, RNBGDTaskConfig config) {
|
||||||
// report begin & progress
|
Log.d(getName(), "RNBD: startReportingTasks-1 downloadId " + downloadId + " config.id " + config.id);
|
||||||
//
|
config.reportedBegin = true;
|
||||||
// overlaped with thread to not block main thread
|
downloadIdToConfig.put(downloadId, config);
|
||||||
new Thread(new Runnable() {
|
saveConfigMap();
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
Log.d(getName(), "RNBD: download-3 downloadId: " + downloadId);
|
|
||||||
|
|
||||||
while (true) {
|
Log.d(getName(), "RNBD: startReportingTasks-2 downloadId: " + downloadId);
|
||||||
WritableMap downloadStatus = downloader.checkDownloadStatus(downloadId);
|
// report begin & progress
|
||||||
int status = downloadStatus.getInt("status");
|
//
|
||||||
|
// overlaped with thread to not block main thread
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
Log.d(getName(), "RNBD: startReportingTasks-3 downloadId: " + downloadId);
|
||||||
|
|
||||||
Log.d(getName(), "RNBD: download-3.1 " + status + " downloadId: " + downloadId);
|
while (true) {
|
||||||
|
WritableMap downloadStatus = downloader.checkDownloadStatus(downloadId);
|
||||||
|
int status = downloadStatus.getInt("status");
|
||||||
|
|
||||||
if (status == DownloadManager.STATUS_RUNNING) {
|
Log.d(getName(), "RNBD: startReportingTasks-3.1 " + status + " downloadId: " + downloadId);
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (status == DownloadManager.STATUS_FAILED || status == DownloadManager.STATUS_SUCCESSFUL) {
|
|
||||||
Log.d(getName(), "RNBD: download-3.2 " + status + " downloadId: " + downloadId);
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
|
|
||||||
Thread.sleep(500);
|
if (status == DownloadManager.STATUS_RUNNING) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (status == DownloadManager.STATUS_FAILED || status == DownloadManager.STATUS_SUCCESSFUL) {
|
||||||
|
Log.d(getName(), "RNBD: startReportingTasks-3.2 " + status + " downloadId: " + downloadId);
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
// EMIT BEGIN
|
Thread.sleep(500);
|
||||||
OnBegin onBeginTh = new OnBegin(config, ee);
|
|
||||||
onBeginTh.start();
|
|
||||||
// wait for onBeginTh to finish
|
|
||||||
onBeginTh.join();
|
|
||||||
|
|
||||||
Log.d(getName(), "RNBD: download-4 downloadId: " + downloadId);
|
|
||||||
OnProgress onProgressTh = new OnProgress(config, downloadId, ee, downloader, progressInterval);
|
|
||||||
onProgressThreads.put(config.id, onProgressTh);
|
|
||||||
onProgressTh.start();
|
|
||||||
Log.d(getName(), "RNBD: download-5 downloadId: " + downloadId);
|
|
||||||
} catch (Exception e) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EMIT BEGIN
|
||||||
|
OnBegin onBeginTh = new OnBegin(config, ee);
|
||||||
|
onBeginTh.start();
|
||||||
|
// wait for onBeginTh to finish
|
||||||
|
onBeginTh.join();
|
||||||
|
|
||||||
|
Log.d(getName(), "RNBD: startReportingTasks-4 downloadId: " + downloadId);
|
||||||
|
OnProgress onProgressTh = new OnProgress(config, downloadId, ee, downloader);
|
||||||
|
onProgressThreads.put(config.id, onProgressTh);
|
||||||
|
onProgressTh.start();
|
||||||
|
Log.d(getName(), "RNBD: startReportingTasks-5 downloadId: " + downloadId);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.d(getName(), "RNBD: Runnable e: " + e.toString());
|
||||||
}
|
}
|
||||||
}).start();
|
}
|
||||||
Log.d(getName(), "RNBD: download-6 downloadId: " + downloadId);
|
}).start();
|
||||||
}
|
Log.d(getName(), "RNBD: startReportingTasks-6 downloadId: " + downloadId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: NOT WORKING WITH DownloadManager FOR NOW
|
// TODO: NOT WORKING WITH DownloadManager FOR NOW
|
||||||
@@ -453,8 +460,8 @@ public class RNBackgroundDownloaderModule extends ReactContextBaseJavaModule {
|
|||||||
|
|
||||||
if (cursor.moveToFirst()) {
|
if (cursor.moveToFirst()) {
|
||||||
do {
|
do {
|
||||||
WritableMap result = downloader.getDownloadStatus(cursor);
|
WritableMap downloadStatus = downloader.getDownloadStatus(cursor);
|
||||||
Long downloadId = Long.parseLong(result.getString("downloadId"));
|
Long downloadId = Long.parseLong(downloadStatus.getString("downloadId"));
|
||||||
|
|
||||||
if (downloadIdToConfig.containsKey(downloadId)) {
|
if (downloadIdToConfig.containsKey(downloadId)) {
|
||||||
Log.d(getName(), "RNBD: checkForExistingDownloads-2");
|
Log.d(getName(), "RNBD: checkForExistingDownloads-2");
|
||||||
@@ -462,15 +469,9 @@ public class RNBackgroundDownloaderModule extends ReactContextBaseJavaModule {
|
|||||||
WritableMap params = Arguments.createMap();
|
WritableMap params = Arguments.createMap();
|
||||||
params.putString("id", config.id);
|
params.putString("id", config.id);
|
||||||
params.putString("metadata", config.metadata);
|
params.putString("metadata", config.metadata);
|
||||||
params.putInt("state", stateMap.get(result.getInt("status")));
|
params.putInt("state", stateMap.get(downloadStatus.getInt("status")));
|
||||||
|
params.putInt("bytesDownloaded", downloadStatus.getInt("bytesDownloaded"));
|
||||||
int bytesDownloaded = result.getInt("bytesDownloaded");
|
params.putInt("bytesTotal", downloadStatus.getInt("bytesTotal"));
|
||||||
params.putInt("bytesDownloaded", bytesDownloaded);
|
|
||||||
|
|
||||||
int bytesTotal = result.getInt("bytesTotal");
|
|
||||||
params.putInt("bytesTotal", bytesTotal);
|
|
||||||
|
|
||||||
params.putDouble("percent", ((double) bytesDownloaded / bytesTotal));
|
|
||||||
|
|
||||||
foundIds.pushMap(params);
|
foundIds.pushMap(params);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,87 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
root: true,
|
env: {
|
||||||
extends: '@react-native',
|
es2020: true,
|
||||||
};
|
jest: true,
|
||||||
|
},
|
||||||
|
parser: '@babel/eslint-parser',
|
||||||
|
extends: [
|
||||||
|
'standard',
|
||||||
|
'eslint:recommended',
|
||||||
|
'plugin:react/recommended',
|
||||||
|
'plugin:react-hooks/recommended',
|
||||||
|
],
|
||||||
|
parserOptions: {
|
||||||
|
ecmaFeatures: {
|
||||||
|
jsx: true,
|
||||||
|
},
|
||||||
|
ecmaVersion: 11,
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
'react',
|
||||||
|
'react-hooks',
|
||||||
|
],
|
||||||
|
settings: {
|
||||||
|
react: {
|
||||||
|
version: 'detect',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
indent: [
|
||||||
|
'error',
|
||||||
|
2, {
|
||||||
|
SwitchCase: 1,
|
||||||
|
ignoredNodes: [
|
||||||
|
'TemplateLiteral',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'template-curly-spacing': 'off',
|
||||||
|
'linebreak-style': [
|
||||||
|
'error',
|
||||||
|
'unix',
|
||||||
|
],
|
||||||
|
quotes: [
|
||||||
|
'error',
|
||||||
|
'single',
|
||||||
|
],
|
||||||
|
semi: [
|
||||||
|
'error',
|
||||||
|
'never',
|
||||||
|
],
|
||||||
|
'comma-dangle': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
arrays: 'always-multiline',
|
||||||
|
objects: 'always-multiline',
|
||||||
|
imports: 'always-multiline',
|
||||||
|
exports: 'never',
|
||||||
|
functions: 'never',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'no-func-assign': 'off',
|
||||||
|
'no-class-assign': 'off',
|
||||||
|
'no-useless-escape': 'off',
|
||||||
|
curly: [2, 'multi', 'consistent'],
|
||||||
|
'react/prop-types': 'off', // TODO: TURN ON AND FIX ALL WARNINGS
|
||||||
|
'react/display-name': 'off',
|
||||||
|
'react-hooks/exhaustive-deps': ['warn', {
|
||||||
|
additionalHooks: '(useAnimatedStyle|useSharedValue|useAnimatedGestureHandler|useAnimatedScrollHandler|useAnimatedProps|useDerivedValue|useAnimatedRef|useAnimatedReact)',
|
||||||
|
// useAnimatedReaction
|
||||||
|
// USE RULE FUNC/FUNC/DEPS
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
globals: {
|
||||||
|
describe: 'readonly',
|
||||||
|
test: 'readonly',
|
||||||
|
jest: 'readonly',
|
||||||
|
expect: 'readonly',
|
||||||
|
fetch: 'readonly',
|
||||||
|
navigator: 'readonly',
|
||||||
|
__DEV__: 'readonly',
|
||||||
|
XMLHttpRequest: 'readonly',
|
||||||
|
FormData: 'readonly',
|
||||||
|
React$Element: 'readonly',
|
||||||
|
requestAnimationFrame: 'readonly',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|||||||
105
index.d.ts
vendored
105
index.d.ts
vendored
@@ -11,50 +11,68 @@ export interface DownloadHeaders {
|
|||||||
|
|
||||||
type SetHeaders = (h: DownloadHeaders) => void;
|
type SetHeaders = (h: DownloadHeaders) => void;
|
||||||
|
|
||||||
export interface TaskInfoObject {
|
|
||||||
id: string;
|
|
||||||
metadata: object | string;
|
|
||||||
|
|
||||||
percent?: number;
|
|
||||||
bytesDownloaded?: number;
|
|
||||||
bytesTotal?: number;
|
|
||||||
|
|
||||||
beginHandler?: Function;
|
|
||||||
progressHandler?: Function;
|
|
||||||
doneHandler?: Function;
|
|
||||||
errorHandler?: Function;
|
|
||||||
}
|
|
||||||
export type TaskInfo = TaskInfoObject;
|
|
||||||
|
|
||||||
export interface BeginHandlerObject {
|
export interface BeginHandlerObject {
|
||||||
expectedBytes: number;
|
expectedBytes: number;
|
||||||
headers: { [key: string]: string };
|
headers: { [key: string]: string };
|
||||||
}
|
}
|
||||||
|
|
||||||
export type BeginHandler = ({
|
export type BeginHandler = ({
|
||||||
expectedBytes,
|
expectedBytes,
|
||||||
headers,
|
headers,
|
||||||
}: BeginHandlerObject) => any;
|
}: BeginHandlerObject) => void;
|
||||||
export type ProgressHandler = (
|
|
||||||
percent: number,
|
export interface ProgressHandlerObject {
|
||||||
bytesDownloaded: number,
|
bytesDownloaded: number
|
||||||
bytesTotal: number
|
bytesTotal: number
|
||||||
) => any;
|
}
|
||||||
export type DoneHandler = () => any;
|
export type ProgressHandler = ({
|
||||||
export type ErrorHandler = (error: any, errorCode: any) => any;
|
bytesDownloaded,
|
||||||
|
bytesTotal,
|
||||||
|
}: ProgressHandlerObject) => void;
|
||||||
|
|
||||||
|
export interface DoneHandlerObject {
|
||||||
|
bytesDownloaded: number
|
||||||
|
bytesTotal: number
|
||||||
|
}
|
||||||
|
export type DoneHandler = ({
|
||||||
|
bytesDownloaded,
|
||||||
|
bytesTotal,
|
||||||
|
}: DoneHandlerObject) => void;
|
||||||
|
|
||||||
|
export interface ErrorHandlerObject {
|
||||||
|
error: string
|
||||||
|
errorCode: number
|
||||||
|
}
|
||||||
|
export type ErrorHandler = ({
|
||||||
|
error,
|
||||||
|
errorCode,
|
||||||
|
}: ErrorHandlerObject) => void;
|
||||||
|
|
||||||
|
export interface TaskInfoObject {
|
||||||
|
id: string;
|
||||||
|
metadata: object | string;
|
||||||
|
|
||||||
|
bytesDownloaded?: number;
|
||||||
|
bytesTotal?: number;
|
||||||
|
|
||||||
|
beginHandler?: BeginHandler;
|
||||||
|
progressHandler?: ProgressHandler;
|
||||||
|
doneHandler?: DoneHandler;
|
||||||
|
errorHandler?: ErrorHandler;
|
||||||
|
}
|
||||||
|
export type TaskInfo = TaskInfoObject;
|
||||||
|
|
||||||
export type DownloadTaskState =
|
export type DownloadTaskState =
|
||||||
| "DOWNLOADING"
|
| 'DOWNLOADING'
|
||||||
| "PAUSED"
|
| 'PAUSED'
|
||||||
| "DONE"
|
| 'DONE'
|
||||||
| "FAILED"
|
| 'FAILED'
|
||||||
| "STOPPED";
|
| 'STOPPED';
|
||||||
|
|
||||||
export interface DownloadTask {
|
export interface DownloadTask {
|
||||||
constructor: (taskInfo: TaskInfo) => DownloadTask;
|
constructor: (taskInfo: TaskInfo) => DownloadTask;
|
||||||
|
|
||||||
id: string;
|
id: string;
|
||||||
state: DownloadTaskState;
|
state: DownloadTaskState;
|
||||||
percent: number;
|
|
||||||
bytesDownloaded: number;
|
bytesDownloaded: number;
|
||||||
bytesTotal: number;
|
bytesTotal: number;
|
||||||
|
|
||||||
@@ -68,18 +86,14 @@ export interface DownloadTask {
|
|||||||
_doneHandler: DoneHandler;
|
_doneHandler: DoneHandler;
|
||||||
_errorHandler: ErrorHandler;
|
_errorHandler: ErrorHandler;
|
||||||
|
|
||||||
pause: () => any;
|
pause: () => void;
|
||||||
resume: () => any;
|
resume: () => void;
|
||||||
stop: () => any;
|
stop: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CheckForExistingDownloads = () => Promise<DownloadTask[]>;
|
export type CheckForExistingDownloads = () => Promise<DownloadTask[]>;
|
||||||
export type EnsureDownloadsAreRunning = () => Promise<void>;
|
export type EnsureDownloadsAreRunning = () => Promise<void>;
|
||||||
|
|
||||||
export interface InitDownloaderOptions {
|
|
||||||
}
|
|
||||||
export type InitDownloader = (options: InitDownloaderOptions) => undefined;
|
|
||||||
|
|
||||||
export interface DownloadOption {
|
export interface DownloadOption {
|
||||||
id: string;
|
id: string;
|
||||||
url: string;
|
url: string;
|
||||||
@@ -88,6 +102,7 @@ export interface DownloadOption {
|
|||||||
metadata?: object;
|
metadata?: object;
|
||||||
isAllowedOverRoaming?: boolean;
|
isAllowedOverRoaming?: boolean;
|
||||||
isAllowedOverMetered?: boolean;
|
isAllowedOverMetered?: boolean;
|
||||||
|
progressInterval?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Download = (options: DownloadOption) => DownloadTask;
|
export type Download = (options: DownloadOption) => DownloadTask;
|
||||||
@@ -97,17 +112,15 @@ export interface Directories {
|
|||||||
documents: string;
|
documents: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const setHeaders: SetHeaders;
|
export const setHeaders: SetHeaders
|
||||||
export const checkForExistingDownloads: CheckForExistingDownloads;
|
export const checkForExistingDownloads: CheckForExistingDownloads
|
||||||
export const ensureDownloadsAreRunning: EnsureDownloadsAreRunning;
|
export const ensureDownloadsAreRunning: EnsureDownloadsAreRunning
|
||||||
export const initDownloader: InitDownloader;
|
export const download: Download
|
||||||
export const download: Download;
|
export const completeHandler: CompleteHandler
|
||||||
export const completeHandler: CompleteHandler;
|
export const directories: Directories
|
||||||
export const directories: Directories;
|
|
||||||
|
|
||||||
export interface RNBackgroundDownloader {
|
export interface RNBackgroundDownloader {
|
||||||
setHeaders: SetHeaders;
|
setHeaders: SetHeaders;
|
||||||
initDownloader: InitDownloader;
|
|
||||||
checkForExistingDownloads: CheckForExistingDownloads;
|
checkForExistingDownloads: CheckForExistingDownloads;
|
||||||
ensureDownloadsAreRunning: EnsureDownloadsAreRunning;
|
ensureDownloadsAreRunning: EnsureDownloadsAreRunning;
|
||||||
download: Download;
|
download: Download;
|
||||||
@@ -115,5 +128,5 @@ export interface RNBackgroundDownloader {
|
|||||||
directories: Directories;
|
directories: Directories;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare const RNBackgroundDownloader: RNBackgroundDownloader;
|
declare const RNBackgroundDownloader: RNBackgroundDownloader
|
||||||
export default RNBackgroundDownloader;
|
export default RNBackgroundDownloader
|
||||||
|
|||||||
49
index.ts
49
index.ts
@@ -1,4 +1,4 @@
|
|||||||
import { NativeModules, NativeEventEmitter, Platform } from 'react-native'
|
import { NativeModules, NativeEventEmitter } from 'react-native'
|
||||||
import DownloadTask from './lib/DownloadTask'
|
import DownloadTask from './lib/DownloadTask'
|
||||||
|
|
||||||
const { RNBackgroundDownloader } = NativeModules
|
const { RNBackgroundDownloader } = NativeModules
|
||||||
@@ -7,50 +7,46 @@ const RNBackgroundDownloaderEmitter = new NativeEventEmitter(RNBackgroundDownloa
|
|||||||
const tasksMap = new Map()
|
const tasksMap = new Map()
|
||||||
let headers = {}
|
let headers = {}
|
||||||
|
|
||||||
RNBackgroundDownloaderEmitter.addListener('downloadBegin', ({ id, expectedBytes, headers }) => {
|
RNBackgroundDownloaderEmitter.addListener('downloadBegin', ({ id, ...rest }) => {
|
||||||
console.log('[RNBackgroundDownloader] downloadBegin', id, expectedBytes, headers)
|
console.log('[RNBackgroundDownloader] downloadBegin', id, rest)
|
||||||
const task = tasksMap.get(id)
|
const task = tasksMap.get(id)
|
||||||
task?.onBegin({ expectedBytes, headers })
|
task?.onBegin(rest)
|
||||||
})
|
})
|
||||||
|
|
||||||
RNBackgroundDownloaderEmitter.addListener('downloadProgress', events => {
|
RNBackgroundDownloaderEmitter.addListener('downloadProgress', events => {
|
||||||
// console.log('[RNBackgroundDownloader] downloadProgress-1', events, tasksMap)
|
// console.log('[RNBackgroundDownloader] downloadProgress-1', events, tasksMap)
|
||||||
for (const event of events) {
|
for (const event of events) {
|
||||||
const task = tasksMap.get(event.id)
|
const { id, ...rest } = event
|
||||||
// console.log('[RNBackgroundDownloader] downloadProgress-2', event.id, task)
|
const task = tasksMap.get(id)
|
||||||
task?.onProgress(event.percent, event.bytesDownloaded, event.bytesTotal)
|
// console.log('[RNBackgroundDownloader] downloadProgress-2', id, task)
|
||||||
|
task?.onProgress(rest)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
RNBackgroundDownloaderEmitter.addListener('downloadComplete', ({ id, location }) => {
|
RNBackgroundDownloaderEmitter.addListener('downloadComplete', ({ id, ...rest }) => {
|
||||||
console.log('[RNBackgroundDownloader] downloadComplete', id, location)
|
console.log('[RNBackgroundDownloader] downloadComplete', id, rest)
|
||||||
const task = tasksMap.get(id)
|
const task = tasksMap.get(id)
|
||||||
task?.onDone({ location })
|
task?.onDone(rest)
|
||||||
|
|
||||||
tasksMap.delete(id)
|
tasksMap.delete(id)
|
||||||
})
|
})
|
||||||
|
|
||||||
RNBackgroundDownloaderEmitter.addListener('downloadFailed', event => {
|
RNBackgroundDownloaderEmitter.addListener('downloadFailed', ({ id, ...rest }) => {
|
||||||
console.log('[RNBackgroundDownloader] downloadFailed', event)
|
console.log('[RNBackgroundDownloader] downloadFailed', id, rest)
|
||||||
const task = tasksMap.get(event.id)
|
const task = tasksMap.get(id)
|
||||||
task?.onError(event.error, event.errorCode)
|
task?.onError(rest)
|
||||||
|
|
||||||
tasksMap.delete(event.id)
|
tasksMap.delete(id)
|
||||||
})
|
})
|
||||||
|
|
||||||
export function setHeaders(h = {}) {
|
export function setHeaders (h = {}) {
|
||||||
if (typeof h !== 'object')
|
if (typeof h !== 'object')
|
||||||
throw new Error('[RNBackgroundDownloader] headers must be an object')
|
throw new Error('[RNBackgroundDownloader] headers must be an object')
|
||||||
|
|
||||||
headers = h
|
headers = h
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initDownloader(options = {}) {
|
export function checkForExistingDownloads () {
|
||||||
if (Platform.OS === 'android')
|
|
||||||
RNBackgroundDownloader.initDownloader(options)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function checkForExistingDownloads() {
|
|
||||||
console.log('[RNBackgroundDownloader] checkForExistingDownloads-1')
|
console.log('[RNBackgroundDownloader] checkForExistingDownloads-1')
|
||||||
return RNBackgroundDownloader.checkForExistingDownloads()
|
return RNBackgroundDownloader.checkForExistingDownloads()
|
||||||
.then(foundTasks => {
|
.then(foundTasks => {
|
||||||
@@ -80,7 +76,7 @@ export function checkForExistingDownloads() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ensureDownloadsAreRunning() {
|
export function ensureDownloadsAreRunning () {
|
||||||
console.log('[RNBackgroundDownloader] ensureDownloadsAreRunning')
|
console.log('[RNBackgroundDownloader] ensureDownloadsAreRunning')
|
||||||
return checkForExistingDownloads()
|
return checkForExistingDownloads()
|
||||||
.then(tasks => {
|
.then(tasks => {
|
||||||
@@ -92,7 +88,7 @@ export function ensureDownloadsAreRunning() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function completeHandler(jobId: string) {
|
export function completeHandler (jobId: string) {
|
||||||
if (jobId == null) {
|
if (jobId == null) {
|
||||||
console.warn('[RNBackgroundDownloader] completeHandler: jobId is empty')
|
console.warn('[RNBackgroundDownloader] completeHandler: jobId is empty')
|
||||||
return
|
return
|
||||||
@@ -109,9 +105,10 @@ type DownloadOptions = {
|
|||||||
metadata?: object,
|
metadata?: object,
|
||||||
isAllowedOverRoaming?: boolean,
|
isAllowedOverRoaming?: boolean,
|
||||||
isAllowedOverMetered?: boolean,
|
isAllowedOverMetered?: boolean,
|
||||||
|
progressInterval?: number,
|
||||||
}
|
}
|
||||||
|
|
||||||
export function download(options: DownloadOptions) {
|
export function download (options: DownloadOptions) {
|
||||||
console.log('[RNBackgroundDownloader] download', options)
|
console.log('[RNBackgroundDownloader] download', options)
|
||||||
if (!options.id || !options.url || !options.destination)
|
if (!options.id || !options.url || !options.destination)
|
||||||
throw new Error('[RNBackgroundDownloader] id, url and destination are required')
|
throw new Error('[RNBackgroundDownloader] id, url and destination are required')
|
||||||
@@ -125,6 +122,7 @@ export function download(options: DownloadOptions) {
|
|||||||
|
|
||||||
if (options.isAllowedOverRoaming == null) options.isAllowedOverRoaming = true
|
if (options.isAllowedOverRoaming == null) options.isAllowedOverRoaming = true
|
||||||
if (options.isAllowedOverMetered == null) options.isAllowedOverMetered = true
|
if (options.isAllowedOverMetered == null) options.isAllowedOverMetered = true
|
||||||
|
if (options.progressInterval == null) options.progressInterval = 1000
|
||||||
|
|
||||||
const task = new DownloadTask({
|
const task = new DownloadTask({
|
||||||
id: options.id,
|
id: options.id,
|
||||||
@@ -145,7 +143,6 @@ export const directories = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
initDownloader,
|
|
||||||
download,
|
download,
|
||||||
checkForExistingDownloads,
|
checkForExistingDownloads,
|
||||||
ensureDownloadsAreRunning,
|
ensureDownloadsAreRunning,
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ static CompletionHandler storedCompletionHandler;
|
|||||||
NSMutableDictionary<NSNumber *, RNBGDTaskConfig *> *taskToConfigMap;
|
NSMutableDictionary<NSNumber *, RNBGDTaskConfig *> *taskToConfigMap;
|
||||||
NSMutableDictionary<NSString *, NSURLSessionDownloadTask *> *idToTaskMap;
|
NSMutableDictionary<NSString *, NSURLSessionDownloadTask *> *idToTaskMap;
|
||||||
NSMutableDictionary<NSString *, NSData *> *idToResumeDataMap;
|
NSMutableDictionary<NSString *, NSData *> *idToResumeDataMap;
|
||||||
NSMutableDictionary<NSString *, NSNumber *> *idToPercentMap;
|
|
||||||
NSMutableDictionary<NSString *, NSDictionary *> *progressReports;
|
NSMutableDictionary<NSString *, NSDictionary *> *progressReports;
|
||||||
NSDate *lastProgressReport;
|
NSDate *lastProgressReport;
|
||||||
NSNumber *sharedLock;
|
NSNumber *sharedLock;
|
||||||
@@ -63,7 +62,6 @@ RCT_EXPORT_MODULE();
|
|||||||
}
|
}
|
||||||
idToTaskMap = [[NSMutableDictionary alloc] init];
|
idToTaskMap = [[NSMutableDictionary alloc] init];
|
||||||
idToResumeDataMap = [[NSMutableDictionary alloc] init];
|
idToResumeDataMap = [[NSMutableDictionary alloc] init];
|
||||||
idToPercentMap = [[NSMutableDictionary alloc] init];
|
|
||||||
NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
|
NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
|
||||||
NSString *sessonIdentifier = [bundleIdentifier stringByAppendingString:@".backgrounddownloadtask"];
|
NSString *sessonIdentifier = [bundleIdentifier stringByAppendingString:@".backgrounddownloadtask"];
|
||||||
sessionConfig = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:sessonIdentifier];
|
sessionConfig = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:sessonIdentifier];
|
||||||
@@ -149,7 +147,6 @@ RCT_EXPORT_MODULE();
|
|||||||
|
|
||||||
if (taskConfig) {
|
if (taskConfig) {
|
||||||
[idToTaskMap removeObjectForKey:taskConfig.id];
|
[idToTaskMap removeObjectForKey:taskConfig.id];
|
||||||
[idToPercentMap removeObjectForKey:taskConfig.id];
|
|
||||||
}
|
}
|
||||||
// TOREMOVE - GIVES ERROR IN JS ON HOT RELOAD
|
// TOREMOVE - GIVES ERROR IN JS ON HOT RELOAD
|
||||||
// if (taskToConfigMap.count == 0) {
|
// if (taskToConfigMap.count == 0) {
|
||||||
@@ -224,7 +221,6 @@ RCT_EXPORT_METHOD(download: (NSDictionary *) options) {
|
|||||||
[[NSUserDefaults standardUserDefaults] setObject:[self serialize: taskToConfigMap] forKey:ID_TO_CONFIG_MAP_KEY];
|
[[NSUserDefaults standardUserDefaults] setObject:[self serialize: taskToConfigMap] forKey:ID_TO_CONFIG_MAP_KEY];
|
||||||
|
|
||||||
idToTaskMap[identifier] = task;
|
idToTaskMap[identifier] = task;
|
||||||
idToPercentMap[identifier] = @0.0;
|
|
||||||
|
|
||||||
[task resume];
|
[task resume];
|
||||||
lastProgressReport = [[NSDate alloc] init];
|
lastProgressReport = [[NSDate alloc] init];
|
||||||
@@ -280,20 +276,17 @@ RCT_EXPORT_METHOD(checkForExistingDownloads: (RCTPromiseResolveBlock)resolve rej
|
|||||||
}
|
}
|
||||||
[task resume];
|
[task resume];
|
||||||
}
|
}
|
||||||
NSNumber *percent = task.countOfBytesExpectedToReceive > 0 ? [NSNumber numberWithFloat:(float)task.countOfBytesReceived/(float)task.countOfBytesExpectedToReceive] : @0.0;
|
|
||||||
|
|
||||||
[idsFound addObject:@{
|
[idsFound addObject:@{
|
||||||
@"id": taskConfig.id,
|
@"id": taskConfig.id,
|
||||||
@"metadata": taskConfig.metadata,
|
@"metadata": taskConfig.metadata,
|
||||||
@"state": [NSNumber numberWithInt: task.state],
|
@"state": [NSNumber numberWithInt: task.state],
|
||||||
@"bytesDownloaded": [NSNumber numberWithLongLong:task.countOfBytesReceived],
|
@"bytesDownloaded": [NSNumber numberWithLongLong:task.countOfBytesReceived],
|
||||||
@"bytesTotal": [NSNumber numberWithLongLong:task.countOfBytesExpectedToReceive],
|
@"bytesTotal": [NSNumber numberWithLongLong:task.countOfBytesExpectedToReceive]
|
||||||
@"percent": percent
|
|
||||||
}];
|
}];
|
||||||
taskConfig.reportedBegin = YES;
|
taskConfig.reportedBegin = YES;
|
||||||
taskToConfigMap[@(task.taskIdentifier)] = taskConfig;
|
taskToConfigMap[@(task.taskIdentifier)] = taskConfig;
|
||||||
idToTaskMap[taskConfig.id] = task;
|
idToTaskMap[taskConfig.id] = task;
|
||||||
idToPercentMap[taskConfig.id] = percent;
|
|
||||||
} else {
|
} else {
|
||||||
[task cancel];
|
[task cancel];
|
||||||
}
|
}
|
||||||
@@ -331,6 +324,7 @@ RCT_EXPORT_METHOD(completeHandler:(nonnull NSString *)jobId
|
|||||||
if (self.bridge) {
|
if (self.bridge) {
|
||||||
if (error == nil) {
|
if (error == nil) {
|
||||||
NSDictionary *responseHeaders = ((NSHTTPURLResponse *)downloadTask.response).allHeaderFields;
|
NSDictionary *responseHeaders = ((NSHTTPURLResponse *)downloadTask.response).allHeaderFields;
|
||||||
|
// TODO: SEND bytesDownloaded AND bytesTotal
|
||||||
[self sendEventWithName:@"downloadComplete" body:@{@"id": taskConfig.id, @"headers": responseHeaders, @"location": taskConfig.destination}];
|
[self sendEventWithName:@"downloadComplete" body:@{@"id": taskConfig.id, @"headers": responseHeaders, @"location": taskConfig.destination}];
|
||||||
} else {
|
} else {
|
||||||
[self sendEventWithName:@"downloadFailed" body:@{@"id": taskConfig.id, @"error": [error localizedDescription]}];
|
[self sendEventWithName:@"downloadFailed" body:@{@"id": taskConfig.id, @"error": [error localizedDescription]}];
|
||||||
@@ -363,12 +357,11 @@ RCT_EXPORT_METHOD(completeHandler:(nonnull NSString *)jobId
|
|||||||
taskCofig.reportedBegin = YES;
|
taskCofig.reportedBegin = YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSNumber *prevPercent = idToPercentMap[taskCofig.id];
|
progressReports[taskCofig.id] = @{
|
||||||
NSNumber *percent = [NSNumber numberWithFloat:(float)bytesTotalWritten/(float)bytesTotalExpectedToWrite];
|
@"id": taskCofig.id,
|
||||||
if ([percent floatValue] - [prevPercent floatValue] > 0.01f) {
|
@"bytesDownloaded": [NSNumber numberWithLongLong: bytesTotalWritten],
|
||||||
progressReports[taskCofig.id] = @{@"id": taskCofig.id, @"bytesDownloaded": [NSNumber numberWithLongLong: bytesTotalWritten], @"bytesTotal": [NSNumber numberWithLongLong: bytesTotalExpectedToWrite], @"percent": percent};
|
@"bytesTotal": [NSNumber numberWithLongLong: bytesTotalExpectedToWrite]
|
||||||
idToPercentMap[taskCofig.id] = percent;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
NSDate *now = [[NSDate alloc] init];
|
NSDate *now = [[NSDate alloc] init];
|
||||||
if ([now timeIntervalSinceDate:lastProgressReport] > 0.25 && progressReports.count > 0) {
|
if ([now timeIntervalSinceDate:lastProgressReport] > 0.25 && progressReports.count > 0) {
|
||||||
@@ -376,6 +369,8 @@ RCT_EXPORT_METHOD(completeHandler:(nonnull NSString *)jobId
|
|||||||
[self sendEventWithName:@"downloadProgress" body:[progressReports allValues]];
|
[self sendEventWithName:@"downloadProgress" body:[progressReports allValues]];
|
||||||
}
|
}
|
||||||
lastProgressReport = now;
|
lastProgressReport = now;
|
||||||
|
// TODO: SHOULD REMOVE ALL progressReports ?
|
||||||
|
// IS IT ALL SENT?
|
||||||
[progressReports removeAllObjects];
|
[progressReports removeAllObjects];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -393,6 +388,7 @@ RCT_EXPORT_METHOD(completeHandler:(nonnull NSString *)jobId
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (self.bridge) {
|
if (self.bridge) {
|
||||||
|
// TODO: SEND error AS IN OBJECT
|
||||||
[self sendEventWithName:@"downloadFailed" body:@{@"id": taskCofig.id, @"error": [error localizedDescription]}];
|
[self sendEventWithName:@"downloadFailed" body:@{@"id": taskCofig.id, @"error": [error localizedDescription]}];
|
||||||
}
|
}
|
||||||
// IF WE CAN'T RESUME TO DOWNLOAD LATER
|
// IF WE CAN'T RESUME TO DOWNLOAD LATER
|
||||||
|
|||||||
@@ -15,13 +15,11 @@ export default class DownloadTask {
|
|||||||
state = 'PENDING'
|
state = 'PENDING'
|
||||||
metadata = {}
|
metadata = {}
|
||||||
|
|
||||||
percent = 0
|
|
||||||
bytesDownloaded = 0
|
bytesDownloaded = 0
|
||||||
bytesTotal = 0
|
bytesTotal = 0
|
||||||
|
|
||||||
constructor (taskInfo: TaskInfo, originalTask?: TaskInfo) {
|
constructor (taskInfo: TaskInfo, originalTask?: TaskInfo) {
|
||||||
this.id = taskInfo.id
|
this.id = taskInfo.id
|
||||||
this.percent = taskInfo.percent ?? 0
|
|
||||||
this.bytesDownloaded = taskInfo.bytesDownloaded ?? 0
|
this.bytesDownloaded = taskInfo.bytesDownloaded ?? 0
|
||||||
this.bytesTotal = taskInfo.bytesTotal ?? 0
|
this.bytesTotal = taskInfo.bytesTotal ?? 0
|
||||||
|
|
||||||
@@ -61,26 +59,27 @@ export default class DownloadTask {
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
onBegin ({ expectedBytes, headers }) {
|
onBegin (params) {
|
||||||
this.state = 'DOWNLOADING'
|
this.state = 'DOWNLOADING'
|
||||||
this.beginHandler?.({ expectedBytes, headers })
|
this.beginHandler?.(params)
|
||||||
}
|
}
|
||||||
|
|
||||||
onProgress (percent, bytesDownloaded, bytesTotal) {
|
onProgress ({ bytesDownloaded, bytesTotal }) {
|
||||||
this.percent = percent
|
|
||||||
this.bytesDownloaded = bytesDownloaded
|
this.bytesDownloaded = bytesDownloaded
|
||||||
this.bytesTotal = bytesTotal
|
this.bytesTotal = bytesTotal
|
||||||
this.progressHandler?.(percent, bytesDownloaded, bytesTotal)
|
this.progressHandler?.({ bytesDownloaded, bytesTotal })
|
||||||
}
|
}
|
||||||
|
|
||||||
onDone ({ location }) {
|
onDone (params) {
|
||||||
this.state = 'DONE'
|
this.state = 'DONE'
|
||||||
this.doneHandler?.({ location })
|
this.bytesDownloaded = params.bytesDownloaded
|
||||||
|
this.bytesTotal = params.bytesTotal
|
||||||
|
this.doneHandler?.(params)
|
||||||
}
|
}
|
||||||
|
|
||||||
onError (error, errorCode) {
|
onError (params) {
|
||||||
this.state = 'FAILED'
|
this.state = 'FAILED'
|
||||||
this.errorHandler?.(error, errorCode)
|
this.errorHandler?.(params)
|
||||||
}
|
}
|
||||||
|
|
||||||
pause () {
|
pause () {
|
||||||
|
|||||||
34
package.json
34
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@kesha-antonov/react-native-background-downloader",
|
"name": "@kesha-antonov/react-native-background-downloader",
|
||||||
"version": "3.0.0-alpha.0",
|
"version": "3.0.0-alpha.1",
|
||||||
"description": "A library for React-Native to help you download large files on iOS and Android both in the foreground and most importantly in the background.",
|
"description": "A library for React-Native to help you download large files on iOS and Android both in the foreground and most importantly in the background.",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react-native",
|
"react-native",
|
||||||
@@ -15,9 +15,8 @@
|
|||||||
"homepage": "https://github.com/kesha-antonov/react-native-background-downloader",
|
"homepage": "https://github.com/kesha-antonov/react-native-background-downloader",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Eko labs",
|
"name": "Eko labs, Kesha Antonov",
|
||||||
"email": "dev@helloeko.com",
|
"email": "innokenty.longway@gmail.com"
|
||||||
"url": "https://developer.helloeko.com"
|
|
||||||
},
|
},
|
||||||
"contributors": [
|
"contributors": [
|
||||||
{
|
{
|
||||||
@@ -56,17 +55,21 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.23.2",
|
"@babel/core": "^7.23.6",
|
||||||
"@babel/eslint-parser": "^7.22.15",
|
"@babel/eslint-parser": "^7.23.3",
|
||||||
"@babel/preset-env": "^7.23.2",
|
"@babel/preset-env": "^7.23.6",
|
||||||
"@babel/runtime": "^7.23.2",
|
"@babel/preset-typescript": "^7.23.3",
|
||||||
"@react-native-community/eslint-config": "^3.2.0",
|
"@babel/runtime": "^7.23.6",
|
||||||
|
"@react-native/babel-preset": "^0.74.0",
|
||||||
|
"@react-native/eslint-config": "^0.74.0",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^6.13.1",
|
||||||
|
"@typescript-eslint/parser": "^6.13.1",
|
||||||
"babel-jest": "^29.7.0",
|
"babel-jest": "^29.7.0",
|
||||||
"eslint": "8.52.0",
|
"eslint": "^8.56.0",
|
||||||
"eslint-config-standard": "^17.1.0",
|
"eslint-config-standard": "^17.1.0",
|
||||||
"eslint-config-standard-jsx": "^11.0.0",
|
"eslint-config-standard-jsx": "^11.0.0",
|
||||||
"eslint-plugin-import": "^2.29.0",
|
"eslint-plugin-import": "^2.29.1",
|
||||||
"eslint-plugin-n": "^16.2.0",
|
"eslint-plugin-n": "^16.5.0",
|
||||||
"eslint-plugin-node": "^11.1.0",
|
"eslint-plugin-node": "^11.1.0",
|
||||||
"eslint-plugin-promise": "^6.1.1",
|
"eslint-plugin-promise": "^6.1.1",
|
||||||
"eslint-plugin-react": "^7.33.2",
|
"eslint-plugin-react": "^7.33.2",
|
||||||
@@ -77,10 +80,11 @@
|
|||||||
"lint-staged": ">=15",
|
"lint-staged": ">=15",
|
||||||
"metro-react-native-babel-preset": "^0.77.0",
|
"metro-react-native-babel-preset": "^0.77.0",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-native": "0.72.6",
|
"react-native": "0.73.0",
|
||||||
"react-native-fs": "^2.20.0",
|
"react-native-fs": "^2.20.0",
|
||||||
"react-native-vector-icons": "^10.0.1",
|
"react-native-vector-icons": "^10.0.3",
|
||||||
"react-test-renderer": "18.2.0"
|
"react-test-renderer": "18.2.0",
|
||||||
|
"typescript": "5.3.3"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react-native": ">=0.57.0"
|
"react-native": ">=0.57.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user